package com.lihuan.common.util;

import cn.hutool.core.util.StrUtil;
import com.lihuan.config.Constant;
import io.jsonwebtoken.*;
import lombok.Data;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * JWT 生成token和提取token信息工具类
 *
 * @author Martin
 */
@Data
public class JWTTokenUtil {
    //使用hs256算法
    static SignatureAlgorithm sa = SignatureAlgorithm.HS256;
    //获取key，使用钉钉appKey 作为jwt 的key值
    private static Key generatorKey() {
        byte[] bin = DatatypeConverter.parseBase64Binary(Constant.appKey);
        Key key = new SecretKeySpec(bin, sa.getJcaName());
        return key;
    }

    /**
     * 将传过来的信息按照 Header，Payload，Signature 的方式组装一个字符串
     *
     * @param payLoad
     * @return
     */
    public static String generateToken(Map<String, Object> payLoad, String userId) {
        //生成JWT的时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        //生成签名的时候使用的秘钥secret,这个方法本地封装了的，一般可以从本地配置文件中读取，切记这个秘钥不能外露哦。它就是你服务端的私钥，在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
        JwtBuilder builder = Jwts.builder().setClaims(payLoad)
                //设置jti(JWT ID)：是JWT的唯一标识
                .setId(UUID.randomUUID().toString())
                //iat: jwt的签发时间
                .setIssuedAt(now)
                //代表这个JWT的主体，即它的所有人，这个是一个json格式的字符串，可以存放什么userid，roldid之类的，作为什么用户的唯一标志。
                .setSubject(userId)
                //设置签名使用的签名算法和签名使用的秘钥
                .signWith(sa, generatorKey());
        return builder.compact();

    }


    /**
     * 将token解析
     *
     * @param token
     * @return
     */
    public static Claims parseJWT(String token) {
        //得到DefaultJwtParser
        token = token.replace("\"","");
        Claims claims = Jwts.parser()
                //设置签名的秘钥
                .setSigningKey(generatorKey())
                //设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        return claims;
    }

    /**
     * 校验token
     *
     * @param token
     * @return
     */
    public static Boolean isVerify(String token) {
        //得到DefaultJwtParser
        Claims claims = Jwts.parser()
                //设置签名的秘钥
                .setSigningKey(generatorKey())
                //设置需要解析的jwt
                .parseClaimsJws(token).getBody();
        if (StrUtil.isNotBlank(claims.get("userId").toString())) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        JWTTokenUtil jwtTokenUtil = new JWTTokenUtil();

    }
}
